#ifndef DATE_H
#define DATE_H

#include <iostream>
#include <string>
using namespace std;

class Date {
public:
  Date(int mm=1, int dd=1, int yyyy=1900);
  Date(string);
  Date(const Date&);

  void set(int m, int d, int y);
  void set(string);
  
  bool operator==(const Date&) const;
  bool operator!=(const Date&) const;
  bool operator<(const Date&) const;
  bool operator>(const Date&) const; 
  bool operator>=(const Date&) const; 
  bool operator<=(const Date&) const; 
  int operator-(const Date&) const; 
  friend ostream& operator<<(ostream&, const Date&);
  friend class ActualActual;
  friend class Thirty360;

private:
  int day_;
  int month_;
  int year_;
  bool leap_;
  
  bool isLeap(int year) const;
  bool isValid(int m, int d, int y);
  bool parse(const string, int&, int&, int&);
};

ostream& operator<<(ostream&, const Date&);
class DayCounter {
public:
  DayCounter();
	virtual double operator()(const Date &, const Date &) = 0;
	virtual DayCounter* clone() const = 0;
	virtual ~DayCounter();
};

class ActualActual : public DayCounter {
public:
	ActualActual();
	~ActualActual();
	double operator()(const Date &, const Date &);
  	ActualActual* clone() const;
};

class Actual360 : public DayCounter {
public:
	Actual360();
	~Actual360();
	double operator()(const Date &, const Date &);
  Actual360* clone() const;
};

class Thirty360 : public DayCounter {
public:
	Thirty360();
	~Thirty360();
	double operator()(const Date &, const Date &);
  Thirty360* clone() const;
};

#endif // DATE_H
